/*
 * @Author: C.
 * @Date: 2023-03-20 16:49:37
 */
import { ref, computed, unref, onMounted } from 'vue';
import { onKeyDown } from '@vueuse/core';
interface ICell {
  index: number | undefined;
  dataIndex: string | undefined;
}
export function useTableKeyboard(props, { getDataSourceRef, wrapRef }) {
  const currentCell = ref<ICell>({
    index: undefined,
    dataIndex: undefined,
  });
  // const isCurrentTable=ref

  const colMap = computed(() => {
    // _colMap inner_colMap
    return inner_colMap.value.filter((item) => {
      return _colMap.value.includes(item);
    });
  });
  const _colMap = ref<string[]>([]);
  const inner_colMap = ref<string[]>([]);
  const cellMap = ref({});
  const rowLength = computed(() => {
    return unref(getDataSourceRef).length;
  });
  function cellColumnChange(data) {
    inner_colMap.value = data.map((item) => {
      return item.dataIndex;
    });
  }

  function cellRegister({ dataIndex, index }, action) {
    if (!cellMap.value[dataIndex]) {
      cellMap.value[dataIndex] = {};
      _colMap.value.push(dataIndex);
    }
    cellMap.value[dataIndex][index] = action;
  }
  function cellClick({ dataIndex, index }) {
    currentCell.value = { dataIndex, index };
  }
  function cellBlur() {
    if (currentCell.value.dataIndex === undefined || currentCell.value.index === undefined) return;
    cellMap.value[currentCell.value.dataIndex as string][currentCell.value.index].handleCancel();
    currentCell.value.dataIndex = undefined;
    currentCell.value.index = undefined;
  }
  function cellFocus({ dataIndex, index }) {
    // console.log(dataIndex, index, colMap.value);
    cellBlur();
    if (dataIndex === undefined || index === undefined) return;
    cellMap.value[dataIndex][index].handleEdit();
  }
  onMounted(() => {
    inner_colMap.value = _colMap.value;
    unref(props).editKeyboard &&
      onKeyDown(
        ['ArrowDown', 'ArrowRight', 'ArrowUp', 'ArrowLeft', 'Enter', 'Tab'],
        (e) => {
          // if (currentCell.value.dataIndex === undefined || currentCell.value.index === undefined) return;
          e.preventDefault();
          let cell: ICell = {
            index: undefined,
            dataIndex: undefined,
          };
          switch (e.code) {
            case 'ArrowLeft':
              cell = arrowLeft();
              break;
            case 'ArrowDown':
              cell = arrowDown();
              break;
            case 'ArrowUp':
              cell = arrowUp();
              break;
            case 'ArrowRight':
              cell = arrowRight();
              break;
            case 'Enter':
              // cell = arrowDown();
              cellBlur();
              break;
            case 'Tab':
              cell = Tab();
              break;
            default:
              break;
          }
          cellFocus(cell);
        },
        {
          target: wrapRef,
        },
      );
  });
  function arrowDown(): ICell {
    let nextIndex = (currentCell.value.index as number) + 1;
    if (nextIndex >= rowLength.value) {
      nextIndex = 0;
    }
    return {
      ...currentCell.value,
      index: nextIndex,
    };
  }
  function arrowRight(): ICell {
    let nextDataIndex = currentCell.value.dataIndex as string;
    const next_idx = colMap.value.indexOf(nextDataIndex) + 1;
    if (next_idx >= colMap.value.length) {
      nextDataIndex = colMap.value[0];
    } else {
      nextDataIndex = colMap.value[next_idx];
    }
    return {
      ...currentCell.value,
      dataIndex: nextDataIndex,
    };
  }
  function arrowUp(): ICell {
    let nextIndex = (currentCell.value.index as number) - 1;
    if (nextIndex < 0) {
      nextIndex = rowLength.value - 1;
    }
    return {
      ...currentCell.value,
      index: nextIndex,
    };
  }
  function arrowLeft(): ICell {
    let nextDataIndex = currentCell.value.dataIndex as string;
    const next_idx = colMap.value.indexOf(nextDataIndex) - 1;
    if (next_idx < 0) {
      nextDataIndex = colMap.value[colMap.value.length - 1];
    } else {
      nextDataIndex = colMap.value[next_idx];
    }
    return {
      ...currentCell.value,
      dataIndex: nextDataIndex,
    };
  }
  function Tab(): ICell {
    let nextDataIndex = currentCell.value.dataIndex as string;
    let nextIndex: undefined | number = undefined;
    const next_idx = colMap.value.indexOf(nextDataIndex) + 1;
    if (next_idx >= colMap.value.length) {
      nextDataIndex = colMap.value[0];
      nextIndex = arrowDown().index;
    } else {
      nextDataIndex = colMap.value[next_idx];
    }
    return {
      index: nextIndex ?? currentCell.value.index,
      dataIndex: nextDataIndex,
    };
  }

  return {
    cellRegister,
    cellClick,
    cellColumnChange,
    cellBlur,
  };
}
